Xinzhu Wang(xw2581)

What makes people happy? It is always a topic deserving exploration and analysis. In the following content, I will discuss the differences of happy moments between male and female, as well as the happy moments for past 24 hours versus 3 months. Also nine different topics of happy moments for each gender will be included. Hope these analysis will provide people a better undersatnd of happiness and how happy moments spark in everyone’s daily life.

I. Import and Clean data

First, I import the original dataset called hm_orig generated by the test-processing.rmd file. Then, the hm dataset is the one I have cleaned the stopwords which is more readable and more convinent to do analysis. Here it shows 6 rows of the data in hm dataset.

hm_orig <- read.csv("~/Documents/GitHub/Spring2019-Proj1-EvelynWangxz/output/processed_moments.csv")
hm <- read.csv("~/Documents/GitHub/Spring2019-Proj1-EvelynWangxz/output/processed_moments_new.csv")
hm_demo <- read.csv("~/Documents/GitHub/Spring2019-Proj1-EvelynWangxz/data/data/demographic.csv")
head(hm,6)
hm_m <- filter(hm,hm$wid %in% filter(hm_demo,gender == "m")$wid)
hm_f <- filter(hm,hm$wid %in% filter(hm_demo,gender == "f")$wid)

Below are some sample code used to clean stopwords. Actually it has been finished in Text_Processing_new.rmd file. I made some deletion in stopwords according to the results of counting the frequencies of each word, like day, time, finally which are uncessary and meaningless to apeear in the following analysis.

#data("stop_words")
#word <- c("happy","ago","yesterday","lot","today","months","month",
#                 "happier","happiest","last","week","past","day","time","finally","feel","enjoyed","moment","nice","favorite","hours","weekend","called","days","enjoy","excited","didnt")
#stop_words <- stop_words %>%
#  bind_rows(mutate(tibble(word), lexicon = "updated"))

II. Explorative Data Analysis

  1. WordCloud for data before deleteing more stop words. In this wordcloud, you can observe that the most common word is “frind”, along with some words like “day”, “time”, “family” and “home”. However, it is very obvious that words like “day” and “time” are meaningless. They will affect the analysis results and cover the real meaningful words. So I coustomize the stopwords list and delete them.
corpus_orig <- VCorpus(VectorSource(hm_orig$text))
tm_orig <- TermDocumentMatrix(corpus_orig)
tm.tidy_orig <- tidy(tm_orig)
tm1_orig <- summarise(group_by(tm.tidy_orig, term), sum(count))
wordcloud(tm1_orig$term, tm1_orig$`sum(count)`, scale=c(2,0.5), max.words=200, min.freq=1, random.order=FALSE, rot.per=0.3, use.r.layout=T, random.color=T, colors=c("purple","pink","lightblue"))

  1. After deleting the custom stopwords, I finalize a brand-new wordcloud. It shows the frequency of each word when you click on the word. In the wordcloud, “friend” is still the most frequent word. There are also some words like “home”, “family”, “son”, “watched”, “game” and “birthday” which illustrate the topic of these happy moments might be related to family and enjoyment activities.
corpus <- VCorpus(VectorSource(hm$text))
tm <- TermDocumentMatrix(corpus)
tm.tidy <- tidy(tm)
tm1 <- summarise(group_by(tm.tidy, term), sum(count))
tm1 <- data.frame(tm1)
tm.red <- head(tm1[order(tm1[,2],decreasing = T),],100)
wordcloud2(tm.red, size=0.7,color='random-light',fontWeight = 'bold',minRotation = -pi/3,maxRotation = pi/3,rotateRatio = 0.8)
  1. After having an overall analysis of the most frequent words in happy moments. I would like to focus on the differences between male and female. Two bar plots below is a comparsion of the top 10 words for male and female. For both male and female, “friend” is the most reliable source of happiness. While, the other words in the top 10 for male show that male are catching happiness more from games, watchting and playing activities which is very different from female’s. For female, they are more likely to get happiness from family like their hubsand, son and daughter. It is barely to see enjoyment words like “games” and “played” in female’s top 10 lists. This observation is shown more clearly in the third barplot which is a directly comparsion of top 20 words between male and female.
m.tidy <- tidy(TermDocumentMatrix(VCorpus(VectorSource(hm_m$text))))
m <- summarise(group_by(m.tidy, term), sum(count))
m <- data.frame(m)
m.red <- head(m[order(m[,2],decreasing = T),],10)
p1 <- ggplot(m.red, aes(x =reorder(m.red$term,m.red$sum.count.),y = m.red$sum.count.)) + geom_bar(stat = "identity", fill = "lightblue") + coord_flip() + xlab("male") + ylab("term")
f.tidy <- tidy(TermDocumentMatrix(VCorpus(VectorSource(hm_f$text))))
f <- summarise(group_by(f.tidy, term), sum(count))
f <- data.frame(f)
f.red <- head(f[order(f[,2],decreasing = T),],10)
p2 <- ggplot(f.red, aes(x =reorder(term,sum.count.),y = sum.count.)) + geom_bar(stat = "identity", fill = "pink") + coord_flip() + xlab("female") + ylab("term")
grid.arrange(p1, p2, nrow = 1, ncol = 2)

For most top 20 words, male and female have similar frequency except the word “friend” and some other words that doesn’t appear in one side. It demonstrates that female pays more attention to family than male who is more care about enjoyments. This observation is very interesting and intuitive. It is more likely to be the nature of gender which puts female and family more tight overally. In addition to this, friend is a very important character in everyone’s life and spending time with friends is the main happiness source.

m.red <- head(m[order(m[,2],decreasing = T),],20)
f.red <- head(f[order(f[,2],decreasing = T),],20)
m.red$sum.count. <- m.red$sum.count.*(-1)
temp1 <- rbind(m.red,f.red)
temp2 <- c(rep("m",20),rep("f",20))
temp1$gender <- temp2 
ggplot(data = temp1, aes(x = reorder(temp1$term, -temp1$sum.count.), y = temp1$sum.count., group = gender, fill = gender)) + geom_bar(position = "stack", stat = "identity") + scale_y_continuous(labels = c(5000,4000,3000,2000,1000,0,1000,2000,3000,4000,5000), breaks = seq(-5000,5000,1000)) + xlab("term") + ylab("frequency") + coord_flip() 

III. LDA Analysis

  1. Using LDA to show the top 10 frequent words of nine different topics of happy moments between male and female. After analyzing the top 10/20 frequent words for both male and female, I would like to show you what kind of topic these words could build. It will illustrate the buildup of happy moments for each gender. For male, accroding to the plot below, I would like to divide the words in nine topics which are “family”, “event”, “entertainment”, “life”, “food”, “shopping”, “school”, “archievement”, “work”. This result is based on the top 10 frequent words in each topic. For example, in one topic, there are words including “game”, “played”, “watched” and “video” which indicate this topic should be entertainment. Doing the same thing to the left will get their topics. These nine topics are pretty reasonable and basically overlap people’s daily lives.
m.data <- hm_m %>% group_by(wid) %>% summarise(text = paste(text, collapse = " "))
m.lda <- LDA(DocumentTermMatrix(Corpus(VectorSource(m.data$text))), k = 9, control = list(seed = 2000))
m.lda.tidy <- tidy(m.lda)
m.top10 <- m.lda.tidy %>% group_by(topic) %>% top_n(10, beta) %>% ungroup() %>% arrange(topic, -beta)
plot_m <- m.top10 %>%mutate(term = reorder(term, beta)) %>% ggplot(aes(term, beta, fill = factor(topic))) +geom_bar(stat = "identity", show.legend = T) +facet_wrap(~ topic, scales = "free") +coord_flip() + ggtitle("Male:Top 10 Words in Nine Topics")
plot_m

For female, accroding to the plot below, I would like to divide the words in nine topics which are “pet”, “shopping”, “family”, “people”, “event”, “entertainment”, “work”, “life”, “people”. Comparing nine topics for male and female, an interesting phenomenon happened. There is a topic called “pet” in female’s data instead of “shopping”. It could show that female is more likely to feel happy from pet in somehow than male. What else, there is a topic “shopping” in both gender. As we all know, female is more carzy about shopping. This conclusion might not be true. Most shopping female do might be around family.

f.data <- hm_f %>% group_by(wid) %>% summarise(text = paste(text, collapse = " "))
f.lda <- LDA(DocumentTermMatrix(Corpus(VectorSource(f.data$text))), k = 9, control = list(seed = 2000))
f.lda.tidy <- tidy(f.lda)
f.top10 <- f.lda.tidy %>% group_by(topic) %>% top_n(10, beta) %>% ungroup() %>% arrange(topic, -beta)
plot_f <- f.top10 %>%mutate(term = reorder(term, beta)) %>% ggplot(aes(term, beta, fill = factor(topic))) +geom_bar(stat = "identity", show.legend = T) +facet_wrap(~ topic, scales = "free") +coord_flip() + ggtitle("Female:Top 10 Words in Nine Topic")
plot_f

IV. Time Effect Analysis

Time is always an effective influence to the content of happy moments. Therefore, I would like to analyze what is the shift between past 24 hours and 3 months in each gender.

  1. Differences of happy moments between male and female for the past 24 hours
hm.m24 <- hm_m[hm_m$reflection_period=="24h",]
hm.f24 <- hm_f[hm_f$reflection_period=="24h",]
hm.m24$gender <- "m"
hm.f24$gender <- "f"
hm24 <- rbind(hm.m24,hm.f24)
hm24_plot <- ggplot(hm24, aes(predicted_category, fill = gender)) + geom_bar() + ggtitle("Predicted Category Distribution for 24 hours") +coord_flip() 
  1. Differences of happy moments between male and female for the past 3 months
hm.m3 <- hm_m[hm_m$reflection_period=="3m",]
hm.f3 <- hm_m[hm_f$reflection_period=="3m",]
hm.m3$gender <- "m"
hm.f3$gender <- "f"
hm3 <- rbind(hm.m3,hm.f3)
hm3_plot <- ggplot(hm3, aes(predicted_category, fill = gender)) + geom_bar() + ggtitle("Predicted Category Distribution for 3 months") +coord_flip() 

For the plot below, it clearly show the differnces for past 24 hours and 3 months. If we ignore the gender issue, we can see that for past 24 hours, affection is the most frequent category in happy moments. The second one is archievement much more than other categories. However, for past 3 months, the most frequent category is archievement and the second one is affection. Actually, for past three months, the total number of affection didn’t increase a lot, but the total of archievement increased rapidly. Also the total number of enjoyment didn’t increase at all. This phenomenon is very special and indicative. It leads me to think of the ture happiness of life. The affection is an emotional release which can not last a long time and commonly be remembered just for a short time. Differently, archievement is enduring no matter for male and female. With the past of time, archievement will be eulogized for a long time accompanyed with more sustainable happiness. In each category, the ratio of male and female is pretty similar except for the enjoyment for past 24 hours. It is true that male will get more happiness from enjoyments like playing video games. However, with the increasing of time, the ratio of enjoyment becomes half and half. Male becomes to pay less attention to enjoyments and focus more on archievement.

grid.arrange(hm24_plot, hm3_plot, nrow = 2, ncol = 1)

  1. HeatMap The heatmap below is a more direct way to compare time effect on each category between male and female. The grid with deeper color indicates the more important position of that category in happy moments. The affection and archievement are very outstanding compared with others. The exercise is very cheerless and only has a little proportion for male in past 24 hours. It can slightly illustrate that male cares more about exercise than female does.
hm.m24$time <- "m24"
hm.f24$time <- "f24"
hm.m3$time <- "m3"
hm.f3$time <- "f3"
hm.time <- rbind(hm.m24,hm.f24,hm.m3,hm.f3)
prop <- function(data){
affection <- data[data$predicted_category=="affection",]
a <- dim(affection)[1]/nrow(data)
leisure <- data[data$predicted_category=="leisure",]
l <- dim(leisure)[1]/nrow(data)
enjoy_the_moment <- data[data$predicted_category=="enjoy_the_moment",]
e <- dim(enjoy_the_moment)[1]/nrow(data)
achievement <- data[data$predicted_category=="achievement",]
ach <- dim(achievement)[1]/nrow(data)
bonding <- data[data$predicted_category=="bonding",]
b <- dim(bonding)[1]/nrow(data)
nature <- data[data$predicted_category=="nature",]
n <- dim(nature)[1]/nrow(data)
exercise <- data[data$predicted_category=="exercise",]
ex <- dim(exercise)[1]/nrow(data)
df <- data.frame(c(a,l,e,ach,b,n,ex))
}
d1 <- prop(hm.f24)
d2 <- prop(hm.m24)
d3 <- prop(hm.f3)
d4 <- prop(hm.m3)
d11 <- rbind(d1,d2,d3,d4)
d22 <- c(rep("f24",7),rep("m24",7),rep("f3",7),rep("m3",7))
d33 <- rep(c("affection","leisure","enjoy_the_moment","achievement","bonding","nature","exercise"),4)
df <- data.frame(d11,d22,d33)
colnames(df) <- c("prop","time","topic")
ggplot(df, aes(x=time,y=topic,fill=prop)) + geom_tile() + scale_fill_gradient2('legend name', low = 'blue', high = 'red') 

V. Conclusion

All in all, based on the analysis above, we have an overall understanding of the differences of happy moments between male and female as well as under different time flows. Bascially, the top 10 frequent words for the two gender groups are very similar. However, male might be more focus on entertainments while female pays more attention on family. Then, for the nine topics generated for male and female. There is a topic called “pet” for female instead of “shopping” for male. This indicates that female might be more interested in pets than male. Finally, the most frequent topic(category) could change as time goes by. For a short time, affection is very influential for both male and female. But archievement catched up quickly with the increase of time. After these analysis, hope people can have a more comprehensive and deeper understand of happy moments in life.

LS0tCnRpdGxlOiAiUHJvamVjdCAxIC0gSGFwcHkgTW9tZW50IEFuYWx5c2lzIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgpgYGB7ciwgbWVzc2FnZT1GLGVjaG89Rn0KbGlicmFyeSh0bSkKbGlicmFyeSh3b3JkY2xvdWQpCmxpYnJhcnkod29yZGNsb3VkMikKbGlicmFyeShkcGx5cikKbGlicmFyeSh0aWR5dGV4dCkKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGZvcmNhdHMpCmxpYnJhcnkodG9waWNtb2RlbHMpCmxpYnJhcnkoZ3JpZEV4dHJhKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeSh0aWR5cikKbGlicmFyeShnZ3JpZGdlcykKYGBgCiNYaW56aHUgV2FuZyh4dzI1ODEpCldoYXQgbWFrZXMgcGVvcGxlIGhhcHB5PyBJdCBpcyBhbHdheXMgYSB0b3BpYyBkZXNlcnZpbmcgZXhwbG9yYXRpb24gYW5kIGFuYWx5c2lzLiBJbiB0aGUgZm9sbG93aW5nIGNvbnRlbnQsIEkgd2lsbCBkaXNjdXNzIHRoZSBkaWZmZXJlbmNlcyBvZiBoYXBweSBtb21lbnRzIGJldHdlZW4gbWFsZSBhbmQgZmVtYWxlLCBhcyB3ZWxsIGFzIHRoZSBoYXBweSBtb21lbnRzIGZvciBwYXN0IDI0IGhvdXJzIHZlcnN1cyAzIG1vbnRocy4gQWxzbyBuaW5lIGRpZmZlcmVudCB0b3BpY3Mgb2YgaGFwcHkgbW9tZW50cyBmb3IgZWFjaCBnZW5kZXIgd2lsbCBiZSBpbmNsdWRlZC4gSG9wZSB0aGVzZSBhbmFseXNpcyB3aWxsIHByb3ZpZGUgcGVvcGxlIGEgYmV0dGVyIHVuZGVyc2F0bmQgb2YgaGFwcGluZXNzIGFuZCBob3cgaGFwcHkgbW9tZW50cyBzcGFyayBpbiBldmVyeW9uZSdzIGRhaWx5IGxpZmUuIAoKIyBJLiBJbXBvcnQgYW5kIENsZWFuIGRhdGEgCgpGaXJzdCwgSSBpbXBvcnQgdGhlIG9yaWdpbmFsIGRhdGFzZXQgY2FsbGVkIGhtX29yaWcgZ2VuZXJhdGVkIGJ5IHRoZSB0ZXN0LXByb2Nlc3Npbmcucm1kIGZpbGUuIFRoZW4sIHRoZSBobSBkYXRhc2V0IGlzIHRoZSBvbmUgSSBoYXZlIGNsZWFuZWQgdGhlIHN0b3B3b3JkcyB3aGljaCBpcyBtb3JlIHJlYWRhYmxlIGFuZCBtb3JlIGNvbnZpbmVudCB0byBkbyBhbmFseXNpcy4gSGVyZSBpdCBzaG93cyA2IHJvd3Mgb2YgdGhlIGRhdGEgaW4gaG0gZGF0YXNldC4gIAoKYGBge3Isd2FybmluZz1GfQpobV9vcmlnIDwtIHJlYWQuY3N2KCJ+L0RvY3VtZW50cy9HaXRIdWIvU3ByaW5nMjAxOS1Qcm9qMS1FdmVseW5XYW5neHovb3V0cHV0L3Byb2Nlc3NlZF9tb21lbnRzLmNzdiIpCmhtIDwtIHJlYWQuY3N2KCJ+L0RvY3VtZW50cy9HaXRIdWIvU3ByaW5nMjAxOS1Qcm9qMS1FdmVseW5XYW5neHovb3V0cHV0L3Byb2Nlc3NlZF9tb21lbnRzX25ldy5jc3YiKQpobV9kZW1vIDwtIHJlYWQuY3N2KCJ+L0RvY3VtZW50cy9HaXRIdWIvU3ByaW5nMjAxOS1Qcm9qMS1FdmVseW5XYW5neHovZGF0YS9kYXRhL2RlbW9ncmFwaGljLmNzdiIpCmBgYAoKYGBge3J9CmhlYWQoaG0sNikKYGBgCgpgYGB7cn0KaG1fbSA8LSBmaWx0ZXIoaG0saG0kd2lkICVpbiUgZmlsdGVyKGhtX2RlbW8sZ2VuZGVyID09ICJtIikkd2lkKQpobV9mIDwtIGZpbHRlcihobSxobSR3aWQgJWluJSBmaWx0ZXIoaG1fZGVtbyxnZW5kZXIgPT0gImYiKSR3aWQpCmBgYAoKQmVsb3cgYXJlIHNvbWUgc2FtcGxlIGNvZGUgdXNlZCB0byBjbGVhbiBzdG9wd29yZHMuIEFjdHVhbGx5IGl0IGhhcyBiZWVuIGZpbmlzaGVkIGluIFRleHRfUHJvY2Vzc2luZ19uZXcucm1kIGZpbGUuIEkgbWFkZSBzb21lIGRlbGV0aW9uIGluIHN0b3B3b3JkcyBhY2NvcmRpbmcgdG8gdGhlIHJlc3VsdHMgb2YgY291bnRpbmcgdGhlIGZyZXF1ZW5jaWVzIG9mIGVhY2ggd29yZCwgbGlrZSBkYXksIHRpbWUsIGZpbmFsbHkgd2hpY2ggYXJlIHVuY2Vzc2FyeSBhbmQgbWVhbmluZ2xlc3MgdG8gYXBlZWFyIGluIHRoZSBmb2xsb3dpbmcgYW5hbHlzaXMuIAoKYGBge3Igc3RvcHdvcmRzfQojZGF0YSgic3RvcF93b3JkcyIpCgojd29yZCA8LSBjKCJoYXBweSIsImFnbyIsInllc3RlcmRheSIsImxvdCIsInRvZGF5IiwibW9udGhzIiwibW9udGgiLAojICAgICAgICAgICAgICAgICAiaGFwcGllciIsImhhcHBpZXN0IiwibGFzdCIsIndlZWsiLCJwYXN0IiwiZGF5IiwidGltZSIsImZpbmFsbHkiLCJmZWVsIiwiZW5qb3llZCIsIm1vbWVudCIsIm5pY2UiLCJmYXZvcml0ZSIsImhvdXJzIiwid2Vla2VuZCIsImNhbGxlZCIsImRheXMiLCJlbmpveSIsImV4Y2l0ZWQiLCJkaWRudCIpCgojc3RvcF93b3JkcyA8LSBzdG9wX3dvcmRzICU+JQojICBiaW5kX3Jvd3MobXV0YXRlKHRpYmJsZSh3b3JkKSwgbGV4aWNvbiA9ICJ1cGRhdGVkIikpCmBgYAoKIyBJSS4gRXhwbG9yYXRpdmUgRGF0YSBBbmFseXNpcwoKMS4gV29yZENsb3VkIGZvciBkYXRhIGJlZm9yZSBkZWxldGVpbmcgbW9yZSBzdG9wIHdvcmRzLgpJbiB0aGlzIHdvcmRjbG91ZCwgeW91IGNhbiBvYnNlcnZlIHRoYXQgdGhlIG1vc3QgY29tbW9uIHdvcmQgaXMgImZyaW5kIiwgYWxvbmcgd2l0aCBzb21lIHdvcmRzIGxpa2UgImRheSIsICJ0aW1lIiwgImZhbWlseSIgYW5kICJob21lIi4gSG93ZXZlciwgaXQgaXMgdmVyeSBvYnZpb3VzIHRoYXQgd29yZHMgbGlrZSAiZGF5IiBhbmQgInRpbWUiIGFyZSBtZWFuaW5nbGVzcy4gVGhleSB3aWxsIGFmZmVjdCB0aGUgYW5hbHlzaXMgcmVzdWx0cyBhbmQgY292ZXIgdGhlIHJlYWwgbWVhbmluZ2Z1bCB3b3Jkcy4gU28gSSBjb3VzdG9taXplIHRoZSBzdG9wd29yZHMgbGlzdCBhbmQgZGVsZXRlIHRoZW0uIApgYGB7cn0KY29ycHVzX29yaWcgPC0gVkNvcnB1cyhWZWN0b3JTb3VyY2UoaG1fb3JpZyR0ZXh0KSkKdG1fb3JpZyA8LSBUZXJtRG9jdW1lbnRNYXRyaXgoY29ycHVzX29yaWcpCnRtLnRpZHlfb3JpZyA8LSB0aWR5KHRtX29yaWcpCnRtMV9vcmlnIDwtIHN1bW1hcmlzZShncm91cF9ieSh0bS50aWR5X29yaWcsIHRlcm0pLCBzdW0oY291bnQpKQpgYGAKCmBgYHtyfQp3b3JkY2xvdWQodG0xX29yaWckdGVybSwgdG0xX29yaWckYHN1bShjb3VudClgLCBzY2FsZT1jKDIsMC41KSwgbWF4LndvcmRzPTIwMCwgbWluLmZyZXE9MSwgcmFuZG9tLm9yZGVyPUZBTFNFLCByb3QucGVyPTAuMywgdXNlLnIubGF5b3V0PVQsIHJhbmRvbS5jb2xvcj1ULCBjb2xvcnM9YygicHVycGxlIiwicGluayIsImxpZ2h0Ymx1ZSIpKQpgYGAKCjIuIEFmdGVyIGRlbGV0aW5nIHRoZSBjdXN0b20gc3RvcHdvcmRzLCBJIGZpbmFsaXplIGEgYnJhbmQtbmV3IHdvcmRjbG91ZC4gSXQgc2hvd3MgdGhlIGZyZXF1ZW5jeSBvZiBlYWNoIHdvcmQgd2hlbiB5b3UgY2xpY2sgb24gdGhlIHdvcmQuIEluIHRoZSB3b3JkY2xvdWQsICJmcmllbmQiIGlzIHN0aWxsIHRoZSBtb3N0IGZyZXF1ZW50IHdvcmQuIFRoZXJlIGFyZSBhbHNvIHNvbWUgd29yZHMgbGlrZSAiaG9tZSIsICJmYW1pbHkiLCAic29uIiwgIndhdGNoZWQiLCAiZ2FtZSIgYW5kICJiaXJ0aGRheSIgd2hpY2ggaWxsdXN0cmF0ZSB0aGUgdG9waWMgb2YgdGhlc2UgaGFwcHkgbW9tZW50cyBtaWdodCBiZSByZWxhdGVkIHRvIGZhbWlseSBhbmQgZW5qb3ltZW50IGFjdGl2aXRpZXMuCmBgYHtyfQpjb3JwdXMgPC0gVkNvcnB1cyhWZWN0b3JTb3VyY2UoaG0kdGV4dCkpCnRtIDwtIFRlcm1Eb2N1bWVudE1hdHJpeChjb3JwdXMpCnRtLnRpZHkgPC0gdGlkeSh0bSkKdG0xIDwtIHN1bW1hcmlzZShncm91cF9ieSh0bS50aWR5LCB0ZXJtKSwgc3VtKGNvdW50KSkKYGBgCgpgYGB7cn0KdG0xIDwtIGRhdGEuZnJhbWUodG0xKQp0bS5yZWQgPC0gaGVhZCh0bTFbb3JkZXIodG0xWywyXSxkZWNyZWFzaW5nID0gVCksXSwxMDApCmBgYAoKYGBge3J9CndvcmRjbG91ZDIodG0ucmVkLCBzaXplPTAuNyxjb2xvcj0ncmFuZG9tLWxpZ2h0Jyxmb250V2VpZ2h0ID0gJ2JvbGQnLG1pblJvdGF0aW9uID0gLXBpLzMsbWF4Um90YXRpb24gPSBwaS8zLHJvdGF0ZVJhdGlvID0gMC44KQpgYGAKCgozLiBBZnRlciBoYXZpbmcgYW4gb3ZlcmFsbCBhbmFseXNpcyBvZiB0aGUgbW9zdCBmcmVxdWVudCB3b3JkcyBpbiBoYXBweSBtb21lbnRzLiBJIHdvdWxkIGxpa2UgdG8gZm9jdXMgb24gdGhlIGRpZmZlcmVuY2VzIGJldHdlZW4gbWFsZSBhbmQgZmVtYWxlLiBUd28gYmFyIHBsb3RzIGJlbG93IGlzIGEgY29tcGFyc2lvbiBvZiB0aGUgdG9wIDEwIHdvcmRzIGZvciBtYWxlIGFuZCBmZW1hbGUuIEZvciBib3RoIG1hbGUgYW5kIGZlbWFsZSwgImZyaWVuZCIgaXMgdGhlIG1vc3QgcmVsaWFibGUgc291cmNlIG9mIGhhcHBpbmVzcy4gV2hpbGUsIHRoZSBvdGhlciB3b3JkcyBpbiB0aGUgdG9wIDEwIGZvciBtYWxlIHNob3cgdGhhdCBtYWxlIGFyZSBjYXRjaGluZyBoYXBwaW5lc3MgbW9yZSBmcm9tIGdhbWVzLCB3YXRjaHRpbmcgYW5kIHBsYXlpbmcgYWN0aXZpdGllcyB3aGljaCBpcyB2ZXJ5IGRpZmZlcmVudCBmcm9tIGZlbWFsZSdzLiBGb3IgZmVtYWxlLCB0aGV5IGFyZSBtb3JlIGxpa2VseSB0byBnZXQgaGFwcGluZXNzIGZyb20gZmFtaWx5IGxpa2UgdGhlaXIgaHVic2FuZCwgc29uIGFuZCBkYXVnaHRlci4gSXQgaXMgYmFyZWx5IHRvIHNlZSBlbmpveW1lbnQgd29yZHMgbGlrZSAiZ2FtZXMiIGFuZCAicGxheWVkIiBpbiBmZW1hbGUncyB0b3AgMTAgbGlzdHMuIFRoaXMgb2JzZXJ2YXRpb24gaXMgc2hvd24gbW9yZSBjbGVhcmx5IGluIHRoZSB0aGlyZCBiYXJwbG90IHdoaWNoIGlzIGEgZGlyZWN0bHkgY29tcGFyc2lvbiBvZiB0b3AgMjAgd29yZHMgYmV0d2VlbiBtYWxlIGFuZCBmZW1hbGUuIAoKYGBge3J9Cm0udGlkeSA8LSB0aWR5KFRlcm1Eb2N1bWVudE1hdHJpeChWQ29ycHVzKFZlY3RvclNvdXJjZShobV9tJHRleHQpKSkpCm0gPC0gc3VtbWFyaXNlKGdyb3VwX2J5KG0udGlkeSwgdGVybSksIHN1bShjb3VudCkpCm0gPC0gZGF0YS5mcmFtZShtKQptLnJlZCA8LSBoZWFkKG1bb3JkZXIobVssMl0sZGVjcmVhc2luZyA9IFQpLF0sMTApCmBgYAoKYGBge3J9CnAxIDwtIGdncGxvdChtLnJlZCwgYWVzKHggPXJlb3JkZXIobS5yZWQkdGVybSxtLnJlZCRzdW0uY291bnQuKSx5ID0gbS5yZWQkc3VtLmNvdW50LikpICsgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIGZpbGwgPSAibGlnaHRibHVlIikgKyBjb29yZF9mbGlwKCkgKyB4bGFiKCJtYWxlIikgKyB5bGFiKCJ0ZXJtIikKYGBgCgpgYGB7cn0KZi50aWR5IDwtIHRpZHkoVGVybURvY3VtZW50TWF0cml4KFZDb3JwdXMoVmVjdG9yU291cmNlKGhtX2YkdGV4dCkpKSkKZiA8LSBzdW1tYXJpc2UoZ3JvdXBfYnkoZi50aWR5LCB0ZXJtKSwgc3VtKGNvdW50KSkKZiA8LSBkYXRhLmZyYW1lKGYpCmYucmVkIDwtIGhlYWQoZltvcmRlcihmWywyXSxkZWNyZWFzaW5nID0gVCksXSwxMCkKYGBgCgpgYGB7cn0KcDIgPC0gZ2dwbG90KGYucmVkLCBhZXMoeCA9cmVvcmRlcih0ZXJtLHN1bS5jb3VudC4pLHkgPSBzdW0uY291bnQuKSkgKyBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgZmlsbCA9ICJwaW5rIikgKyBjb29yZF9mbGlwKCkgKyB4bGFiKCJmZW1hbGUiKSArIHlsYWIoInRlcm0iKQpgYGAKCmBgYHtyfQpncmlkLmFycmFuZ2UocDEsIHAyLCBucm93ID0gMSwgbmNvbCA9IDIpCmBgYAoKRm9yIG1vc3QgdG9wIDIwIHdvcmRzLCBtYWxlIGFuZCBmZW1hbGUgaGF2ZSBzaW1pbGFyIGZyZXF1ZW5jeSBleGNlcHQgdGhlIHdvcmQgImZyaWVuZCIgYW5kIHNvbWUgb3RoZXIgd29yZHMgdGhhdCBkb2Vzbid0IGFwcGVhciBpbiBvbmUgc2lkZS4gSXQgZGVtb25zdHJhdGVzIHRoYXQgZmVtYWxlIHBheXMgbW9yZSBhdHRlbnRpb24gdG8gZmFtaWx5IHRoYW4gbWFsZSB3aG8gaXMgbW9yZSBjYXJlIGFib3V0IGVuam95bWVudHMuIFRoaXMgb2JzZXJ2YXRpb24gaXMgdmVyeSBpbnRlcmVzdGluZyBhbmQgaW50dWl0aXZlLiBJdCBpcyBtb3JlIGxpa2VseSB0byBiZSB0aGUgbmF0dXJlIG9mIGdlbmRlciB3aGljaCBwdXRzIGZlbWFsZSBhbmQgZmFtaWx5IG1vcmUgdGlnaHQgb3ZlcmFsbHkuIEluIGFkZGl0aW9uIHRvIHRoaXMsIGZyaWVuZCBpcyBhIHZlcnkgaW1wb3J0YW50IGNoYXJhY3RlciBpbiBldmVyeW9uZSdzIGxpZmUgYW5kIHNwZW5kaW5nIHRpbWUgd2l0aCBmcmllbmRzIGlzIHRoZSBtYWluIGhhcHBpbmVzcyBzb3VyY2UuICAKCmBgYHtyfQptLnJlZCA8LSBoZWFkKG1bb3JkZXIobVssMl0sZGVjcmVhc2luZyA9IFQpLF0sMjApCmYucmVkIDwtIGhlYWQoZltvcmRlcihmWywyXSxkZWNyZWFzaW5nID0gVCksXSwyMCkKbS5yZWQkc3VtLmNvdW50LiA8LSBtLnJlZCRzdW0uY291bnQuKigtMSkKdGVtcDEgPC0gcmJpbmQobS5yZWQsZi5yZWQpCnRlbXAyIDwtIGMocmVwKCJtIiwyMCkscmVwKCJmIiwyMCkpCnRlbXAxJGdlbmRlciA8LSB0ZW1wMiAKZ2dwbG90KGRhdGEgPSB0ZW1wMSwgYWVzKHggPSByZW9yZGVyKHRlbXAxJHRlcm0sIC10ZW1wMSRzdW0uY291bnQuKSwgeSA9IHRlbXAxJHN1bS5jb3VudC4sIGdyb3VwID0gZ2VuZGVyLCBmaWxsID0gZ2VuZGVyKSkgKyBnZW9tX2Jhcihwb3NpdGlvbiA9ICJzdGFjayIsIHN0YXQgPSAiaWRlbnRpdHkiKSArIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBjKDUwMDAsNDAwMCwzMDAwLDIwMDAsMTAwMCwwLDEwMDAsMjAwMCwzMDAwLDQwMDAsNTAwMCksIGJyZWFrcyA9IHNlcSgtNTAwMCw1MDAwLDEwMDApKSArIHhsYWIoInRlcm0iKSArIHlsYWIoImZyZXF1ZW5jeSIpICsgY29vcmRfZmxpcCgpIApgYGAKCiMgSUlJLiBMREEgQW5hbHlzaXMgCjEuIFVzaW5nIExEQSB0byBzaG93IHRoZSB0b3AgMTAgZnJlcXVlbnQgd29yZHMgb2YgbmluZSBkaWZmZXJlbnQgdG9waWNzIG9mIGhhcHB5IG1vbWVudHMgYmV0d2VlbiBtYWxlIGFuZCBmZW1hbGUuCkFmdGVyIGFuYWx5emluZyB0aGUgdG9wIDEwLzIwIGZyZXF1ZW50IHdvcmRzIGZvciBib3RoIG1hbGUgYW5kIGZlbWFsZSwgSSB3b3VsZCBsaWtlIHRvIHNob3cgeW91IHdoYXQga2luZCBvZiB0b3BpYyB0aGVzZSB3b3JkcyBjb3VsZCBidWlsZC4gSXQgd2lsbCBpbGx1c3RyYXRlIHRoZSBidWlsZHVwIG9mIGhhcHB5IG1vbWVudHMgZm9yIGVhY2ggZ2VuZGVyLiAKRm9yIG1hbGUsIGFjY3JvZGluZyB0byB0aGUgcGxvdCBiZWxvdywgSSB3b3VsZCBsaWtlIHRvIGRpdmlkZSB0aGUgd29yZHMgaW4gbmluZSB0b3BpY3Mgd2hpY2ggYXJlICJmYW1pbHkiLCAiZXZlbnQiLCAiZW50ZXJ0YWlubWVudCIsICJsaWZlIiwgImZvb2QiLCAic2hvcHBpbmciLCAic2Nob29sIiwgImFyY2hpZXZlbWVudCIsICJ3b3JrIi4gVGhpcyByZXN1bHQgaXMgYmFzZWQgb24gdGhlIHRvcCAxMCBmcmVxdWVudCB3b3JkcyBpbiBlYWNoIHRvcGljLiBGb3IgZXhhbXBsZSwgaW4gb25lIHRvcGljLCB0aGVyZSBhcmUgd29yZHMgaW5jbHVkaW5nICJnYW1lIiwgInBsYXllZCIsICJ3YXRjaGVkIiBhbmQgInZpZGVvIiB3aGljaCBpbmRpY2F0ZSB0aGlzIHRvcGljIHNob3VsZCBiZSBlbnRlcnRhaW5tZW50LiBEb2luZyB0aGUgc2FtZSB0aGluZyB0byB0aGUgbGVmdCB3aWxsIGdldCB0aGVpciB0b3BpY3MuIFRoZXNlIG5pbmUgdG9waWNzIGFyZSBwcmV0dHkgcmVhc29uYWJsZSBhbmQgYmFzaWNhbGx5IG92ZXJsYXAgcGVvcGxlJ3MgZGFpbHkgbGl2ZXMuIAoKYGBge3J9Cm0uZGF0YSA8LSBobV9tICU+JSBncm91cF9ieSh3aWQpICU+JSBzdW1tYXJpc2UodGV4dCA9IHBhc3RlKHRleHQsIGNvbGxhcHNlID0gIiAiKSkKbS5sZGEgPC0gTERBKERvY3VtZW50VGVybU1hdHJpeChDb3JwdXMoVmVjdG9yU291cmNlKG0uZGF0YSR0ZXh0KSkpLCBrID0gOSwgY29udHJvbCA9IGxpc3Qoc2VlZCA9IDIwMDApKQptLmxkYS50aWR5IDwtIHRpZHkobS5sZGEpCm0udG9wMTAgPC0gbS5sZGEudGlkeSAlPiUgZ3JvdXBfYnkodG9waWMpICU+JSB0b3BfbigxMCwgYmV0YSkgJT4lIHVuZ3JvdXAoKSAlPiUgYXJyYW5nZSh0b3BpYywgLWJldGEpCmBgYAoKYGBge3J9CnBsb3RfbSA8LSBtLnRvcDEwICU+JW11dGF0ZSh0ZXJtID0gcmVvcmRlcih0ZXJtLCBiZXRhKSkgJT4lIGdncGxvdChhZXModGVybSwgYmV0YSwgZmlsbCA9IGZhY3Rvcih0b3BpYykpKSArZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHNob3cubGVnZW5kID0gVCkgK2ZhY2V0X3dyYXAofiB0b3BpYywgc2NhbGVzID0gImZyZWUiKSArY29vcmRfZmxpcCgpICsgZ2d0aXRsZSgiTWFsZTpUb3AgMTAgV29yZHMgaW4gTmluZSBUb3BpY3MiKQpwbG90X20KYGBgCgpGb3IgZmVtYWxlLCBhY2Nyb2RpbmcgdG8gdGhlIHBsb3QgYmVsb3csIEkgd291bGQgbGlrZSB0byBkaXZpZGUgdGhlIHdvcmRzIGluIG5pbmUgdG9waWNzIHdoaWNoIGFyZSAicGV0IiwgInNob3BwaW5nIiwgImZhbWlseSIsICJwZW9wbGUiLCAiZXZlbnQiLCAiZW50ZXJ0YWlubWVudCIsICJ3b3JrIiwgImxpZmUiLCAicGVvcGxlIi4gQ29tcGFyaW5nIG5pbmUgdG9waWNzIGZvciBtYWxlIGFuZCBmZW1hbGUsIGFuIGludGVyZXN0aW5nIHBoZW5vbWVub24gaGFwcGVuZWQuIFRoZXJlIGlzIGEgdG9waWMgY2FsbGVkICJwZXQiIGluIGZlbWFsZSdzIGRhdGEgaW5zdGVhZCBvZiAic2hvcHBpbmciLiBJdCBjb3VsZCBzaG93IHRoYXQgZmVtYWxlIGlzIG1vcmUgbGlrZWx5IHRvIGZlZWwgaGFwcHkgZnJvbSBwZXQgaW4gc29tZWhvdyB0aGFuIG1hbGUuIFdoYXQgZWxzZSwgdGhlcmUgaXMgYSB0b3BpYyAic2hvcHBpbmciIGluIGJvdGggZ2VuZGVyLiBBcyB3ZSBhbGwga25vdywgZmVtYWxlIGlzIG1vcmUgY2FyenkgYWJvdXQgc2hvcHBpbmcuIFRoaXMgY29uY2x1c2lvbiBtaWdodCBub3QgYmUgdHJ1ZS4gTW9zdCBzaG9wcGluZyBmZW1hbGUgZG8gbWlnaHQgYmUgYXJvdW5kIGZhbWlseS4gICAKCmBgYHtyfQpmLmRhdGEgPC0gaG1fZiAlPiUgZ3JvdXBfYnkod2lkKSAlPiUgc3VtbWFyaXNlKHRleHQgPSBwYXN0ZSh0ZXh0LCBjb2xsYXBzZSA9ICIgIikpCmYubGRhIDwtIExEQShEb2N1bWVudFRlcm1NYXRyaXgoQ29ycHVzKFZlY3RvclNvdXJjZShmLmRhdGEkdGV4dCkpKSwgayA9IDksIGNvbnRyb2wgPSBsaXN0KHNlZWQgPSAyMDAwKSkKZi5sZGEudGlkeSA8LSB0aWR5KGYubGRhKQpmLnRvcDEwIDwtIGYubGRhLnRpZHkgJT4lIGdyb3VwX2J5KHRvcGljKSAlPiUgdG9wX24oMTAsIGJldGEpICU+JSB1bmdyb3VwKCkgJT4lIGFycmFuZ2UodG9waWMsIC1iZXRhKQpgYGAKCmBgYHtyfQpwbG90X2YgPC0gZi50b3AxMCAlPiVtdXRhdGUodGVybSA9IHJlb3JkZXIodGVybSwgYmV0YSkpICU+JSBnZ3Bsb3QoYWVzKHRlcm0sIGJldGEsIGZpbGwgPSBmYWN0b3IodG9waWMpKSkgK2dlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBzaG93LmxlZ2VuZCA9IFQpICtmYWNldF93cmFwKH4gdG9waWMsIHNjYWxlcyA9ICJmcmVlIikgK2Nvb3JkX2ZsaXAoKSArIGdndGl0bGUoIkZlbWFsZTpUb3AgMTAgV29yZHMgaW4gTmluZSBUb3BpYyIpCnBsb3RfZgpgYGAKCiMgSVYuIFRpbWUgRWZmZWN0IEFuYWx5c2lzClRpbWUgaXMgYWx3YXlzIGFuIGVmZmVjdGl2ZSBpbmZsdWVuY2UgdG8gdGhlIGNvbnRlbnQgb2YgaGFwcHkgbW9tZW50cy4gVGhlcmVmb3JlLCBJIHdvdWxkIGxpa2UgdG8gYW5hbHl6ZSB3aGF0IGlzIHRoZSBzaGlmdCBiZXR3ZWVuIHBhc3QgMjQgaG91cnMgYW5kIDMgbW9udGhzIGluIGVhY2ggZ2VuZGVyLiAgCgoxLiBEaWZmZXJlbmNlcyBvZiBoYXBweSBtb21lbnRzIGJldHdlZW4gbWFsZSBhbmQgZmVtYWxlIGZvciB0aGUgcGFzdCAyNCBob3VycwoKYGBge3J9CmhtLm0yNCA8LSBobV9tW2htX20kcmVmbGVjdGlvbl9wZXJpb2Q9PSIyNGgiLF0KaG0uZjI0IDwtIGhtX2ZbaG1fZiRyZWZsZWN0aW9uX3BlcmlvZD09IjI0aCIsXQpobS5tMjQkZ2VuZGVyIDwtICJtIgpobS5mMjQkZ2VuZGVyIDwtICJmIgpobTI0IDwtIHJiaW5kKGhtLm0yNCxobS5mMjQpCmhtMjRfcGxvdCA8LSBnZ3Bsb3QoaG0yNCwgYWVzKHByZWRpY3RlZF9jYXRlZ29yeSwgZmlsbCA9IGdlbmRlcikpICsgZ2VvbV9iYXIoKSArIGdndGl0bGUoIlByZWRpY3RlZCBDYXRlZ29yeSBEaXN0cmlidXRpb24gZm9yIDI0IGhvdXJzIikgK2Nvb3JkX2ZsaXAoKSAKYGBgCgoKMi4gRGlmZmVyZW5jZXMgb2YgaGFwcHkgbW9tZW50cyBiZXR3ZWVuIG1hbGUgYW5kIGZlbWFsZSBmb3IgdGhlIHBhc3QgMyBtb250aHMKCmBgYHtyfQpobS5tMyA8LSBobV9tW2htX20kcmVmbGVjdGlvbl9wZXJpb2Q9PSIzbSIsXQpobS5mMyA8LSBobV9tW2htX2YkcmVmbGVjdGlvbl9wZXJpb2Q9PSIzbSIsXQpobS5tMyRnZW5kZXIgPC0gIm0iCmhtLmYzJGdlbmRlciA8LSAiZiIKaG0zIDwtIHJiaW5kKGhtLm0zLGhtLmYzKQpobTNfcGxvdCA8LSBnZ3Bsb3QoaG0zLCBhZXMocHJlZGljdGVkX2NhdGVnb3J5LCBmaWxsID0gZ2VuZGVyKSkgKyBnZW9tX2JhcigpICsgZ2d0aXRsZSgiUHJlZGljdGVkIENhdGVnb3J5IERpc3RyaWJ1dGlvbiBmb3IgMyBtb250aHMiKSArY29vcmRfZmxpcCgpIApgYGAKCkZvciB0aGUgcGxvdCBiZWxvdywgaXQgY2xlYXJseSBzaG93IHRoZSBkaWZmZXJuY2VzIGZvciBwYXN0IDI0IGhvdXJzIGFuZCAzIG1vbnRocy4gSWYgd2UgaWdub3JlIHRoZSBnZW5kZXIgaXNzdWUsIHdlIGNhbiBzZWUgdGhhdCBmb3IgcGFzdCAyNCBob3VycywgYWZmZWN0aW9uIGlzIHRoZSBtb3N0IGZyZXF1ZW50IGNhdGVnb3J5IGluIGhhcHB5IG1vbWVudHMuIFRoZSBzZWNvbmQgb25lIGlzIGFyY2hpZXZlbWVudCBtdWNoIG1vcmUgdGhhbiBvdGhlciBjYXRlZ29yaWVzLiBIb3dldmVyLCBmb3IgcGFzdCAzIG1vbnRocywgdGhlIG1vc3QgZnJlcXVlbnQgY2F0ZWdvcnkgaXMgYXJjaGlldmVtZW50IGFuZCB0aGUgc2Vjb25kIG9uZSBpcyBhZmZlY3Rpb24uIEFjdHVhbGx5LCBmb3IgcGFzdCB0aHJlZSBtb250aHMsIHRoZSB0b3RhbCBudW1iZXIgb2YgYWZmZWN0aW9uIGRpZG4ndCBpbmNyZWFzZSBhIGxvdCwgYnV0IHRoZSB0b3RhbCBvZiBhcmNoaWV2ZW1lbnQgaW5jcmVhc2VkIHJhcGlkbHkuIEFsc28gdGhlIHRvdGFsIG51bWJlciBvZiBlbmpveW1lbnQgZGlkbid0IGluY3JlYXNlIGF0IGFsbC4gVGhpcyBwaGVub21lbm9uIGlzIHZlcnkgc3BlY2lhbCBhbmQgaW5kaWNhdGl2ZS4gSXQgbGVhZHMgbWUgdG8gdGhpbmsgb2YgdGhlIHR1cmUgaGFwcGluZXNzIG9mIGxpZmUuIFRoZSBhZmZlY3Rpb24gaXMgYW4gZW1vdGlvbmFsIHJlbGVhc2Ugd2hpY2ggY2FuIG5vdCBsYXN0IGEgbG9uZyB0aW1lIGFuZCBjb21tb25seSBiZSByZW1lbWJlcmVkIGp1c3QgZm9yIGEgc2hvcnQgdGltZS4gRGlmZmVyZW50bHksIGFyY2hpZXZlbWVudCBpcyBlbmR1cmluZyBubyBtYXR0ZXIgZm9yIG1hbGUgYW5kIGZlbWFsZS4gV2l0aCB0aGUgcGFzdCBvZiB0aW1lLCBhcmNoaWV2ZW1lbnQgd2lsbCBiZSBldWxvZ2l6ZWQgZm9yIGEgbG9uZyB0aW1lIGFjY29tcGFueWVkIHdpdGggbW9yZSBzdXN0YWluYWJsZSBoYXBwaW5lc3MuCkluIGVhY2ggY2F0ZWdvcnksIHRoZSByYXRpbyBvZiBtYWxlIGFuZCBmZW1hbGUgaXMgcHJldHR5IHNpbWlsYXIgZXhjZXB0IGZvciB0aGUgZW5qb3ltZW50IGZvciBwYXN0IDI0IGhvdXJzLiBJdCBpcyB0cnVlIHRoYXQgbWFsZSB3aWxsIGdldCBtb3JlIGhhcHBpbmVzcyBmcm9tIGVuam95bWVudHMgbGlrZSBwbGF5aW5nIHZpZGVvIGdhbWVzLiBIb3dldmVyLCB3aXRoIHRoZSBpbmNyZWFzaW5nIG9mIHRpbWUsIHRoZSByYXRpbyBvZiBlbmpveW1lbnQgYmVjb21lcyBoYWxmIGFuZCBoYWxmLiBNYWxlIGJlY29tZXMgdG8gcGF5IGxlc3MgYXR0ZW50aW9uIHRvIGVuam95bWVudHMgYW5kIGZvY3VzIG1vcmUgb24gYXJjaGlldmVtZW50LiAKCmBgYHtyfQpncmlkLmFycmFuZ2UoaG0yNF9wbG90LCBobTNfcGxvdCwgbnJvdyA9IDIsIG5jb2wgPSAxKQpgYGAKCjMuIEhlYXRNYXAKVGhlIGhlYXRtYXAgYmVsb3cgaXMgYSBtb3JlIGRpcmVjdCB3YXkgdG8gY29tcGFyZSB0aW1lIGVmZmVjdCBvbiBlYWNoIGNhdGVnb3J5IGJldHdlZW4gbWFsZSBhbmQgZmVtYWxlLiBUaGUgZ3JpZCB3aXRoIGRlZXBlciBjb2xvciBpbmRpY2F0ZXMgdGhlIG1vcmUgaW1wb3J0YW50IHBvc2l0aW9uIG9mIHRoYXQgY2F0ZWdvcnkgaW4gaGFwcHkgbW9tZW50cy4gVGhlIGFmZmVjdGlvbiBhbmQgYXJjaGlldmVtZW50IGFyZSB2ZXJ5IG91dHN0YW5kaW5nIGNvbXBhcmVkIHdpdGggb3RoZXJzLiBUaGUgZXhlcmNpc2UgaXMgdmVyeSBjaGVlcmxlc3MgYW5kIG9ubHkgaGFzIGEgbGl0dGxlIHByb3BvcnRpb24gZm9yIG1hbGUgaW4gcGFzdCAyNCBob3Vycy4gSXQgY2FuIHNsaWdodGx5IGlsbHVzdHJhdGUgdGhhdCBtYWxlIGNhcmVzIG1vcmUgYWJvdXQgZXhlcmNpc2UgdGhhbiBmZW1hbGUgZG9lcy4KCmBgYHtyfQpobS5tMjQkdGltZSA8LSAibTI0IgpobS5mMjQkdGltZSA8LSAiZjI0IgpobS5tMyR0aW1lIDwtICJtMyIKaG0uZjMkdGltZSA8LSAiZjMiCmhtLnRpbWUgPC0gcmJpbmQoaG0ubTI0LGhtLmYyNCxobS5tMyxobS5mMykKCnByb3AgPC0gZnVuY3Rpb24oZGF0YSl7CmFmZmVjdGlvbiA8LSBkYXRhW2RhdGEkcHJlZGljdGVkX2NhdGVnb3J5PT0iYWZmZWN0aW9uIixdCmEgPC0gZGltKGFmZmVjdGlvbilbMV0vbnJvdyhkYXRhKQpsZWlzdXJlIDwtIGRhdGFbZGF0YSRwcmVkaWN0ZWRfY2F0ZWdvcnk9PSJsZWlzdXJlIixdCmwgPC0gZGltKGxlaXN1cmUpWzFdL25yb3coZGF0YSkKZW5qb3lfdGhlX21vbWVudCA8LSBkYXRhW2RhdGEkcHJlZGljdGVkX2NhdGVnb3J5PT0iZW5qb3lfdGhlX21vbWVudCIsXQplIDwtIGRpbShlbmpveV90aGVfbW9tZW50KVsxXS9ucm93KGRhdGEpCmFjaGlldmVtZW50IDwtIGRhdGFbZGF0YSRwcmVkaWN0ZWRfY2F0ZWdvcnk9PSJhY2hpZXZlbWVudCIsXQphY2ggPC0gZGltKGFjaGlldmVtZW50KVsxXS9ucm93KGRhdGEpCmJvbmRpbmcgPC0gZGF0YVtkYXRhJHByZWRpY3RlZF9jYXRlZ29yeT09ImJvbmRpbmciLF0KYiA8LSBkaW0oYm9uZGluZylbMV0vbnJvdyhkYXRhKQpuYXR1cmUgPC0gZGF0YVtkYXRhJHByZWRpY3RlZF9jYXRlZ29yeT09Im5hdHVyZSIsXQpuIDwtIGRpbShuYXR1cmUpWzFdL25yb3coZGF0YSkKZXhlcmNpc2UgPC0gZGF0YVtkYXRhJHByZWRpY3RlZF9jYXRlZ29yeT09ImV4ZXJjaXNlIixdCmV4IDwtIGRpbShleGVyY2lzZSlbMV0vbnJvdyhkYXRhKQpkZiA8LSBkYXRhLmZyYW1lKGMoYSxsLGUsYWNoLGIsbixleCkpCn0KZDEgPC0gcHJvcChobS5mMjQpCmQyIDwtIHByb3AoaG0ubTI0KQpkMyA8LSBwcm9wKGhtLmYzKQpkNCA8LSBwcm9wKGhtLm0zKQpkMTEgPC0gcmJpbmQoZDEsZDIsZDMsZDQpCmQyMiA8LSBjKHJlcCgiZjI0Iiw3KSxyZXAoIm0yNCIsNykscmVwKCJmMyIsNykscmVwKCJtMyIsNykpCmQzMyA8LSByZXAoYygiYWZmZWN0aW9uIiwibGVpc3VyZSIsImVuam95X3RoZV9tb21lbnQiLCJhY2hpZXZlbWVudCIsImJvbmRpbmciLCJuYXR1cmUiLCJleGVyY2lzZSIpLDQpCmRmIDwtIGRhdGEuZnJhbWUoZDExLGQyMixkMzMpCmNvbG5hbWVzKGRmKSA8LSBjKCJwcm9wIiwidGltZSIsInRvcGljIikKYGBgCgpgYGB7cn0KZ2dwbG90KGRmLCBhZXMoeD10aW1lLHk9dG9waWMsZmlsbD1wcm9wKSkgKyBnZW9tX3RpbGUoKSArIHNjYWxlX2ZpbGxfZ3JhZGllbnQyKCdsZWdlbmQgbmFtZScsIGxvdyA9ICdibHVlJywgaGlnaCA9ICdyZWQnKSAKYGBgCgojIFYuIENvbmNsdXNpb24KCkFsbCBpbiBhbGwsIGJhc2VkIG9uIHRoZSBhbmFseXNpcyBhYm92ZSwgd2UgaGF2ZSBhbiBvdmVyYWxsIHVuZGVyc3RhbmRpbmcgb2YgdGhlIGRpZmZlcmVuY2VzIG9mIGhhcHB5IG1vbWVudHMgYmV0d2VlbiBtYWxlIGFuZCBmZW1hbGUgYXMgd2VsbCBhcyB1bmRlciBkaWZmZXJlbnQgdGltZSBmbG93cy4gQmFzY2lhbGx5LCB0aGUgdG9wIDEwIGZyZXF1ZW50IHdvcmRzIGZvciB0aGUgdHdvIGdlbmRlciBncm91cHMgYXJlIHZlcnkgc2ltaWxhci4gSG93ZXZlciwgbWFsZSBtaWdodCBiZSBtb3JlIGZvY3VzIG9uIGVudGVydGFpbm1lbnRzIHdoaWxlIGZlbWFsZSBwYXlzIG1vcmUgYXR0ZW50aW9uIG9uIGZhbWlseS4gVGhlbiwgZm9yIHRoZSBuaW5lIHRvcGljcyBnZW5lcmF0ZWQgZm9yIG1hbGUgYW5kIGZlbWFsZS4gVGhlcmUgaXMgYSB0b3BpYyBjYWxsZWQgInBldCIgZm9yIGZlbWFsZSBpbnN0ZWFkIG9mICJzaG9wcGluZyIgZm9yIG1hbGUuIFRoaXMgaW5kaWNhdGVzIHRoYXQgZmVtYWxlIG1pZ2h0IGJlIG1vcmUgaW50ZXJlc3RlZCBpbiBwZXRzIHRoYW4gbWFsZS4gRmluYWxseSwgdGhlIG1vc3QgZnJlcXVlbnQgdG9waWMoY2F0ZWdvcnkpIGNvdWxkIGNoYW5nZSBhcyB0aW1lIGdvZXMgYnkuIEZvciBhIHNob3J0IHRpbWUsIGFmZmVjdGlvbiBpcyB2ZXJ5IGluZmx1ZW50aWFsIGZvciBib3RoIG1hbGUgYW5kIGZlbWFsZS4gQnV0IGFyY2hpZXZlbWVudCBjYXRjaGVkIHVwIHF1aWNrbHkgd2l0aCB0aGUgaW5jcmVhc2Ugb2YgdGltZS4gQWZ0ZXIgdGhlc2UgYW5hbHlzaXMsIGhvcGUgcGVvcGxlIGNhbiBoYXZlIGEgbW9yZSBjb21wcmVoZW5zaXZlIGFuZCBkZWVwZXIgdW5kZXJzdGFuZCBvZiBoYXBweSBtb21lbnRzIGluIGxpZmUuCg==